約 3,685,781 件
https://w.atwiki.jp/ghostrecon2001mods/pages/16.html
このページでは、ゴーストリコンのMod導入の基礎について解説する予定です。 はじめに Mod導入リスクについて インターネットのサイトや他のコンピュータからファイルを取得・実行したりする以上、MODの導入には大小のリスクが伴います。従って、modのダウンロードや導入の判断は、起こりうる危険をよく理解したうえで自己責任のもと行ってください。 Modについて Modは、有志が自らの時間や労力を費やして制作し、他のプレイヤーのために(基本的に無償で)配布するゲーム拡張コンテンツです。ゴーストリコンの場合、それは新しいミッション、キャラクターに武器や、ゲームの見た目も中身も一新した全く新しいストーリーキャンペーンなど、多岐に渡ります。その趣やクオリティは様々ですが、その殆どが有志ファンによるゲームへの愛と労力の塊であることを、頭の片隅にでも置いておいてもらえればと思います。 Mod導入手順 圧縮ファイル(アーカイブ)の場合 (7zやzip等) 1. Modファイルをダウンロードする。 多くのゴーストリコン用modは「.7z」や「.zip」といった形式の圧縮ファイルとして配布されていますが、初期(2000年代)に作成された古いものには「.exe」形式のものもあります。これらの多くはインストーラー・ソフトを用いて作られたアーカイブで、実行すると「どこにファイルを展開したいかと聞いて」きます。 2. 圧縮ファイルを展開(解凍)。 7zipなら、modに使われる大抵の圧縮ファイル形式(zipや7z)は展開できる。 展開前後にウイルス対策ソフトでスキャンを(特にexe)。 7-Zipは以下の公式サイトからダウンロードできます。 https //7-zip.org/ 3. 展開したModのメインフォルダーを、ゴーストリコンの「Mods」フォルダに移動またはコピー・ペースト。 Modによっては、メインのmodフォルダーが別のフォルダー内に入っていることもあります。その際は「modscont.txt」というファイルが入ったフォルダーを「Mods」に移動します。 正しく行えば、ファイルパスは以下のようになります。 ¥Ghost recon¥Mods¥導入するModのフォルダ¥modscont.txt 4. Modフォルダー内の「modscont.txt」を開き、「NAME」欄でmodのゲーム内表示名を確認。 「modscont.txt」ファイル*は、ゲームがModを認識する上で基本的に必須のファイルです。このファイルには、規定のフォーマットに基づきmodの名前が記載されているほか、作者やバージョン情報、またその他クレジット表記等がある場合もあります。Modによっては、これと別に「readme」ファイルも付属します。 (*大文字小文字は関係ない模様。「ModsCont.txt」表記もあり) 5. ゲームを起動し、Modが「AVAILABLE MODS」(使用可能なmod)リストに表示されていることを確認。 「Options」 「Mods」から。「AVAILABLE MODS」は使用可能な未起動のMod、「ACTIVE MODS」は起動済みのModのリストです。公式拡張コンテンツであるデザートシージやアイランドサンダーもここに表示されます。 6. 導入するModをリストから選択し、起動する。 リストのModをクリックした後、画面中央の「ACTIVATE」(起動)ボタンをクリックする。 起動済みのModを停止する場合は、「ACTIVE MODS」からmodを選択し「DEACTIVATE」をクリックする。 7. 「ACCEPT」をクリックし変更を保存する。 「ACCEPT」((変更の)了承)ボタンを押さなければ、Modの起動・停止・優先順序変更等の変更は保存されないので、この手順は必ず踏んでください。
https://w.atwiki.jp/oblivion1/pages/163.html
低レベルトレーナー(〜50) Felen Relas(Anvilのメイジギルド) S drassa(Leyawiinのメイジギルド) 中レベルトレーナー(〜70) Ardaline(Bravilのメイジギルド) Brotch Calus(Brumaの聖堂) マスタートレーナー(〜100) Sinderion*(SkingradのWest Wealds Inn 地下) Tamkika wine 399 と Surilie Brothers Wine 399 の2本のワインを持っていかないと訓練してくれない。Skingrad城のダイニングホールからパクるのが一番手っ取り早い。 *サブクエ「根を探せ」と同じジジイ。 [#p06d28ed]
https://w.atwiki.jp/callofduty4pc/pages/98.html
● Call of Duty 4 Map and Mod Tools v1.1 (604MB/画像/動画/08.1.19更新) CoD4のModと、シングル、マルチのカスタムマップ作成を支援するための公式ツール集です。 ・ 現在のところ英語のみのサポート ・ XP互換モードでの動作報告はあるが、基本的にVistaでの動作は不可 ・ パッチ済みのCoD4、Shader3.0対応のDX9ビデオカード、NET Framework Ver2.0以上が必要 導入 : DLして解凍した中身を「Call of Duty 4 - Modern Warfare」フォルダに展開して、 コンパイルツール (\bin\CoD4CompileTools\ CoD4CompileTools.exe) と Modビルダー (\bin\MoDBuilder.exe) のショートカットを任意の場所に作成します。 http //www.infinityward.com/wiki/index.php?title=Mod_Tools_Download_and_Revision_History Call of Duty 4 Mod Tools Wiki (本家・英語) : http //www.infinityward.com/wiki/ Call of Duty 4 Mod Tools 日本語 Community Wiki : http //www13.atwiki.jp/cod4mod/ *) Modツールを使用するには、CoD4フォルダ下に多数のフォルダを展開する必要があります。 使う当てのない人は入れないほうがいいかも。 Modの導入方法 <シングルプレイModの場合> 1) ダウンロードしたファイルを解凍し、その中にある拡張子 ”****.iwd” ファイルなどが入っているフォルダ ”mymod (仮名)” をまるごと、CoD4をインストールした場所にある以下のフォルダ内にコピーします。 ~\Program Files\Activision\Call of Duty 4 - Modern Warfare\Mods Modファイルが ”****.iwd” のみの場合は、”Mods” フォルダ下に”mymod (仮名/任意の名前でよい)” フォルダを新規作成するか、現在使用しているModのフォルダに一緒に入れてください。 2) CoD4シングルプレイのショートカット (”iw3sp.exe” のショートカット) を右クリック → ”プロパティ” → ”リンク先(T)” の文末に以下の命令文を追加します。 ~\Call of Duty 4 - Modern Warfare\iw3sp.exe" +set fs_game mods/mymod 3) 2)で作成したショートカットから起動すると、”mymod” フォルダ内のModがプレイに反映されます。 複数のModを同時に使用する場合は、使いたいModの ”iwd” ファイルを ” +set fs_game mods/” で指定した1つのModフォルダにまとめて入れて下さい。 4) Modを外す時は、該当Modの ”iwd” ファイルを ”mymod” フォルダから除去するか、”mymod” フォルダ 自体を削除してください。 <マルチプレイModの場合> 1) シングルプレイModと同じ手順で、”Mods” フォルダ下に各Mod用のフォルダをコピーします。 2) CoD4マルチプレイのショートカット (”iw3mp.exe” のショートカット) を右クリック → ”プロパティ” → ”リンク先” の文末に以下の命令文を追加します。 ~\Call of Duty 4 - Modern Warfare\iw3mp.exe" +set fs_game mods/mymod 3) またはCoD4マルチプレイを起動し、メニュー画面の ”Mods” から適用したいModのフォルダを選択して ”Launch” を押します。 適用されているModを外すには ”Mods” → ”Launch without Mod” を選択します。 <カスタムMAPの場合> 1) ダウンロードしたファイルを解凍し、その中の”****.iwd”や”****.ff”ファイルなどが入っているMAP名の フォルダ ”mp_mymap (仮名)” を、CoD4をインストールした場所にある以下のフォルダ内にコピーします。 ~\Program Files\Activision\Call of Duty 4 - Modern Warfare\usermaps ”usermaps”フォルダがない場合は新規に作成してください。 2) 1)と同じMAPを導入しているマルチプレイサーバーに接続してプレイします。 3) 一人で導入済みのMAPを探索したいときは、CoD4マルチプレイを起動し、メニュー画面から ”Mods” → ”ModWarfare” を選択して ”Launch” を押します。 4) メニュー画面でコンソール(Ctrl+半角/全角キー)を開いて、”map mp_mymap” と入力します。 *) コンソールに長い文を入力する時は、事前に文をコピーしておけば ”Ctrl”+”V” キーで入力場所にペースト できて便利です。 *) マルチプレイでは”Options”→”Multiplayer Options”→”Allow Downloading”を”Yes”にすると サーバーに接続すると同時に、ModやMAPなどの必要なファイルをプレーヤーのHDDへダウンロードします。 但し、サーバー側のアップロード回線が細かったり、DLするファイルが膨大な場合には、事前にサーバーの 管理者が運営するサイトなどから必要なファイルをDLして導入しておく必要があります。 *) 基本的にカスタムMAPを含むModを導入しているサーバーでは、敵を倒してもRankを上げるための XPを獲得することはできません。 但しModによっては独自のRankを設けているものもあります。
https://w.atwiki.jp/aoonikishi/pages/14.html
サーバーに導入しているMOD MOD名 詳細 CraftBukkit 色々なMODを入れられる様になるMODです。 LWC 主にチェスト・ドア・看板を保護する目的です。 MyHome ホーム地点を設定することで、コマンドを打てばいつでもホーム地点へワープができるようになります。 Tombstone チェストがインベントリにある状態で死亡するとその地点に死亡時のアイテムが入ったチェストができます。※1 Stargate 黒曜石で作るポータルの右側にスイッチ左側に看板を設置することでワープゲートを作れます。※2 Signlift 看板の二段目に[LIFT UP]、[LIFT DOWN]と書くと簡易なリフトができます。X軸とZ軸が同じ場所に作るのが条件です。 Dynmap とても便利なリアルタイムのマップを見ることができます。マップのURLは放送ページで確認してください。 日本語化MOD 日本語でチャットができるようになります。このMODを導入していない人はプレイできますが日本語チャットは使えません。 SimpleSort 木の棒でチェストを左クリックするとID順に整理できます。コマンドを使うことでインベントリの整理も可能です。※3 WoolTrees 木の苗木に染料を与えると20%の確率でその染料の羊毛出できた木ができます。 Citizens NPCを自由に配置できるようになるプラグインです。 Player API 他のMODを導入するための前提MOD Smart Moving プレイヤーの動きをリアルにするMOD(クロールで泳ぐ等) クライアント(個人)に導入しているMOD※4 ModLoader 他のMODを導入するための前提MOD 日本語化MOD チャットで日本語が打てるようになります 私(管理者)が個人的に導入しているMOD※5 ModLoaderMP 上記に同じく前提MOD Player API 上記に同じく前提MOD Smart Moving プレイヤーの動きをリアルにするMOD(クロールで泳ぐ等) SpawnChecker 敵MOBがスポーンする地点を表示します(沸き潰し用) ※1ただし、チェスト一つに入りきらないアイテムはそのまま落ちるようです。 ※2現在PermissionEXを導入していないため使用権限はOPのみになっております。 ※3木の棒を使用したソートはOPのみですが、コマンドを使ったソートの権限はどなたでも可のようです。 ※4クライアント用MODを導入せずともマルチで遊ぶことはできますが、導入を推奨いたします。 ※5導入する必要性は全くありません。しかし使用しているMODということで表記しております。
https://w.atwiki.jp/nitendo/pages/8085.html
NINTENDO 64 Nintendo Switch Online とは、【Nintendo Switch】用のゲーム。 別バージョンの『NINTENDO 64 Nintendo Switch Online 18+』もこちらで合わせて解説する。 概要 収録ソフト 2021年 2022年 2023年 2024年 関連作品 リンク コメント 概要 NINTENDO 64 Nintendo Switch Online ふりがな にんてんどうろくじゅうよん にんてんどーすいっちおんらいん ハード 【Nintendo Switch】 メディア ダウンロード専用 ジャンル オムニバス 発売元 任天堂 プレイ人数 1~4人 発売日 2021/10/26 (日本) 値段 無料(Nintendo Switch Online+追加パック加入者限定) レーティング CERO C(15歳以上対象)『18+』 CERO Z(18歳以上対象) 対応機能 インターネット通信 【Nintendo Switch】向けに配信されたオムニバスソフト。【ファミリーコンピュータ Nintendo Switch Online】の【NINTENDO64】版。 【Nintendo Switch Online】+追加パックの加入者限定でプレイが可能。 基本事項はそちらと同様で、クイックセーブ・オンラインプレイ・アプリ版Switch Onlineを使用したボイスチャットに対応。 FC・SFCのNintendo Switch Onlineでは未対応だった4人までの同時プレイに対応している。 ただしコントローラーパックや64GBパックの再現はない。また他の機種である、巻き戻し機能には対応していない。 2023/11/30からは『NINTENDO 64 Nintendo Switch Online 18+』が別ソフトとして配信。レーティングが18歳以上のタイトルはそちらで配信される。 日本国外では【Nintendo 64 - Nintendo Switch Online】?が代わりに配信されており、一部タイトルが異なる。 タイトルは不定期で追加予定と告知されている。 収録ソフト 発売当時と状況が異なる会社が存在するため、配信元のメーカーは別のメーカーに変わってる場合がある。 2021年 配信日 タイトル メーカー 備考 10/26 【スーパーマリオ64】 任天堂 パッケージは通常版だが、実際の内容は振動パック対応版。 10/26 【スターフォックス64】 任天堂 10/26 【ゼルダの伝説 時のオカリナ】 任天堂 10/26 罪と罰 地球の後継者 任天堂 10/26 【マリオカート64】 任天堂 コース内の広告が海外版基準に変更 10/26 【マリオテニス64】 任天堂 10/26 【ヨッシーストーリー】 任天堂 10/26 WIN BACK コーエーテクモゲームス 12/10 【マリオストーリー】 任天堂 2022年 配信日 タイトル メーカー 備考 01/21 【バンジョーとカズーイの大冒険】 Xbox Game Studios 情報公開時は任天堂が配給メーカーだったが、現在はXbox Game Studiosに変わっている。 02/25 【ゼルダの伝説 ムジュラの仮面】 任天堂 03/11 【F-ZERO X】 任天堂 04/15 【マリオゴルフ64】 任天堂 05/20 【星のカービィ64】 任天堂 06/24 【ポケモンスナップ】 任天堂 07/15 カスタムロボ 任天堂 07/15 【カスタムロボV2】? 任天堂 08/19 【ウエーブレース64】 任天堂 振動パック対応版 10/13 【パイロットウイングス64】 任天堂 11/02 【マリオパーティ】 任天堂 初移植 起動時に警告が出る 11/02 【マリオパーティ2】 任天堂 2023年 配信日 タイトル メーカー 備考 04/12 【ポケモンスタジアム2】 任天堂 初移植 08/08 【ポケモンスタジアム金銀】 任天堂 初移植 08/30 【エキサイトバイク64】? 任天堂 10/27 【マリオパーティ3】 任天堂 初移植 11/30 【ゴールデンアイ 007】 任天堂 『18+』で配信。 11/30 【スターツインズ】? 任天堂 『18+』で配信。 12/08 【テン・エイティ スノーボーディング】 任天堂 12/08 牧場物語2 マーベラス 2024年 配信日 タイトル メーカー 備考 04/24 【ブラストドーザー】 任天堂 06/19 【パーフェクトダーク】? 任天堂 『18+』で配信。 関連作品 【NINTENDO64】 【Nintendo Switch Online】 【バーチャルコンソール】 他の機種のバージョン 【ファミリーコンピュータ Nintendo Switch Online】 【スーパーファミコン Nintendo Switch Online】 【セガ メガドライブ for Nintendo Switch Online】 【ゲームボーイ Nintendo Switch Online】 【ゲームボーイアドバンス Nintendo Switch Online】 The 64DREAM当時のNINTENDO64専門誌。配信タイトル追加時に当時のゲーム記事が、公式トピックスに掲載されることがある。 リンク 公式ホームページ コメント マリオパーティ3いつ配信されるか気になります。 - 名無しさん (2023-07-14 20 19 29) 現状ではSwitchOnlineのレトロゲーで巻き戻しに唯一対応していない。他機種と比べて巻き戻すために記録しておかないといけない1分間のデータの量(=64のメモリの量)が多いからだと思われる。 - 名無しさん (2023-08-12 03 42 45) 本家Wikipediaでパーフェクトダークの今回の移植の良くないところが列挙されてる…項目出来たら記述されるんだろうか - 名無しさん (2024-06-22 16 15 42) 名前 全てのコメントを見る
https://w.atwiki.jp/oblivion1/pages/162.html
注)マスタートレーナーは、中レベルトレーナーから場所を聞かないと訓練してくれない。 また簡単なクエストを要求される。 [[Acrobatics(軽業) ./Acrobatics(軽業)トレーナー]] [[Alchemy(薬学) ./Alchemy(薬学)トレーナー]] [[Alteration(変成魔法) ./Alteration(変成魔法)トレーナー]] [[Armorer(修理) ./Armorer(修理)トレーナー]] [[Athletics(運動能力) ./Athletics(運動能力)トレーナー]] [[Blade(刀剣武器) ./Blade(刀剣武器)トレーナー]] [[Block(防御) ./Block(防御)トレーナー]] [[Blunt(打撃武器) ./Blunt(打撃武器)トレーナー]] [[Conjuration(召喚魔法) ./Conjuration(召喚魔法)トレーナー]] [[Destruction(破壊魔法) ./Destruction(破壊魔法)トレーナー]] [[Hand to Hand(格闘) ./Hand to Hand(格闘)トレーナー]] [[Heavy Armor(重装鎧習熟) ./Heavy Armor(重装鎧習熟)トレーナー]] [[Illusion(幻惑魔法) ./Illusion(幻惑魔法) トレーナー]] [[Light Armor(軽装鎧習熟) ./Light Armor(軽装鎧習熟)トレーナー]] [[Marksman(射撃武器) ./Marksman(射撃武器) トレーナー]] [[Mercantile(商談) ./Mercantile(商談)トレーナー]] [[Mysticism(神秘魔法) ./Mysticism(神秘魔法)トレーナー]] [[Restoration(治癒魔法) ./Restoration(治癒魔法)トレーナー]] [[Security(開錠) ./Security(開錠)トレーナー]] [[Sneak(隠密行動) ./Sneak(隠密行動)トレーナー]] [[Speechcraft(話術) ./Speechcraft(話術)トレーナー]]
https://w.atwiki.jp/bannerlord/pages/92.html
基本事項用語 実装パターン レイヤー追加パターンの実装例Example UI Opponent Health Bar 基本事項 用語 Gauntlet UI Bannerlord のユーザーインターフェースに用いられているフレームワークです。 Model-View-ViewModel アーキテクチャー Gauntlet UI は Model-View-ViewModel (MVVM) と呼ばれるアーキテクチャーパターンを採用しています。要は、ゲームの領域、UI の領域、その2つを仲介する領域、の3層に分離させることで、情報を整理しやすく、また分業しやすくするという発想のようです。UI の MOD の場合、実装が必要なのはこの内の View と ViewModel になります。 この辺は、WPF や XAML を触ったことのある方ならお馴染みなのかもしれませんが、そうでない方も、あまり深く考えずに概念として何となく把握していれば大丈夫です。 ウィジェット GUI を構成する部品です。TaleWorlds.GauntletUI や TaleWorlds.MountAndBlade.GauntletUI.Widgets あたりに一通り揃っています。基本的にはこれらで事足りるので、自分でウィジェットを定義するということはあまり無いのではないかと思われます。 Prefab GUI のレイアウトを定義する XML ファイルです。プレハブ建築のプレハブと同じで、出来合いの部品 (ウィジェットや他の Prefab) をどういう風に組み合わせて配置するかを指定し、なにがしかの UI 機能を提供する大きめの部品として独立させたものです。 Prefab は TaleWorlds.Engine.GauntletUI.GauntletLayer.LoadMovie() するたびに読み込まれるので、ゲーム起動中にレイアウトを確認しながら編集していくなんてこともできます。(もちろん、構文エラー等があればその時点でクラッシュしますが) Brush GUI のスタイルを定義する XML ファイルです。Prefab と Brush の関係は、HTML と CSS の関係と似たようなものだそうです。 Widget に複数の状態が定義されていれば、それぞれの状態に応じたスプライト画像やフォント等を Brush に持たせることで、Widget に視覚的変化を与えることができます。例えば、Wiget がデフォルト状態にある時のスプライト、マウスオーバー時のスプライト、クリックした時のスプライト、Disable 時のスプライトなどをまとめられる、と言えばわかりやすいでしょうか。 ブラシは、Native 等の公式モジュールの GUI\Brushes に多数定義されています。 実装パターン 一部のパターンでしか実験していません。「たぶんこういうことだろう」レベルの推測が混じっています。 追加 既存の UI スクリーンにレイヤーを追加し、そこに自前の GUI を描画する (AddLayer)。 標準的な方法です。自分で View も ViewModel も用意するので好きなようにデザインできますが、既存の GUI そのものを書き換えることはできません。 モジュールとしての競合は起こりませんが、意図せず他の MOD の GUI と表示位置がかぶってしまうことはあり得ます。 改変 (未検証) 既存の UI スクリーンのレイアウトだけを変更する (XML 改変)。 使用するデータソース (ViewModel) はそのままで、XML の書き換えによって GUI の配置なんかを変える方法です。簡単だと思いますが、おそらくやれることは限定的です。また、MOD の競合が発生しうる方法だと思われます。 上書き (未検証) 既存の UI スクリーン全体をオーバーライドする (OverrideView)。 上書きする UI スクリーンが提供していた機能を自分で実装することになるため難易度は高いでしょう。また、MOD の競合が発生しうる方法だと思われます。 新規作成 自前の UI スクリーンを作成し、何かのイベントに伴ってそのスクリーンを呼び出す (PushScreen)。 Push/Pop のスタック形式なのでモーダルなポップアップとかに向いていると思います。 一部改変 たとえばオプション項目の追加などがこれに当たりますが、現状ではできないようです。 ただ、可能にする方法は検討されているとのこと。 Beyond that, we continue to work on Adding support for adding options to the options screen レイヤー追加パターンの実装例 Example UI ExampleUI プロジェクトSubModule.cs ViewsSampleMapView.cs SampleMissionView.cs ViewModelsTestWindowVM.cs ExampleUI.Window.xml View と ViewModel の関係がはっきりするように階層 (名前空間) を分けています。 ExampleUI.Window.xml は、 [Bannerlord インストールフォルダー]\Modules\ExampleUI\GUI\Prefabs フォルダーを作成し、その中に保存します。 MVVM では疎結合 (各層の結びつきが緩やか) なのが望ましいとされているそうなので、参照はできるだけ一方向になるようにしましょう。 すなわち、 View が ViewModel のインスタンスを持ち、その逆方向のアクセスはしない Model (ゲーム内の要素) に属するデータの加工は View の中では行わず、ViewModel で行う という感じです。 コード +SubModule.cs モジュールのエントリーポイントです。 using ExampleUI.Views;using SandBox.View.Map;using System;using TaleWorlds.Core;using TaleWorlds.Engine.Screens;using TaleWorlds.MountAndBlade;using TaleWorlds.MountAndBlade.View.Missions;using TaleWorlds.MountAndBlade.View.Screen; namespace ExampleUI{ public class SubModule MBSubModuleBase { private MissionView _missionView; private MapView _mapView; // Mission (平たく言えば、キャラクターが動き回ったり攻撃したりできる状況) に対する // MOD の処理 (ビヘイビアー) の登録はこのメソッドで行います。 // OnBeforeMissionBehaviourInitialize() と OnMissionBehaviourInitialize() の違いは // MissionBehaviour.OnBehaviourInitialize() の前に呼ばれるか後によばれるかです。 public override void OnBeforeMissionBehaviourInitialize(Mission mission) { base.OnBeforeMissionBehaviourInitialize(mission); // ViewCreatorManager.CreateMissionView() は一応ファクトリーメソッドっぽいのですが、 // 公式のコードには、これを介さず単に new MissionView() しているものもあったりして // よく分かりません。どっちにしろ動くのは動きます。 _missionView = ViewCreatorManager.CreateMissionView SampleMissionView (false, mission, Array.Empty object ()); mission.AddMissionBehaviour(_missionView); /* mission.AddMissionBehaviour(_missionView = new SampleMissionView()); */ // このサンプルでは、全ての Mission でテスト GUI が表示されてしまいますが、 // 戦闘シーンだけに表示したいなどといった場合、何らかの工夫が必要になるでしょう。 // // ちなみに、OnBeforeMissionBehaviourInitialize() 時点で mission.Mode は MissionMode.StartUp 固定なので、 // 以下の方法は使えませんでした。 /* if (mission.Mode == MissionMode.Battle) { _missionView = ViewCreatorManager.CreateMissionView SampleMissionView (false, mission, Array.Empty object ()); mission.AddMissionBehaviour(_missionView); } */ } // MapScreen (ワールドマップの描画スクリーン) には OnBeforeMissionBehaviourInitialize() に相当する // メソッドが用意されていないので、スクリーンの Push/Pop イベントを利用してレイヤーを挿入しています。 public override void OnGameInitializationFinished(Game game) { base.OnGameInitializationFinished(game); ScreenManager.OnPushScreen += OnScreenManagerPushScreen; // Obsolete /* ScreenManager.OnPopScreen += OnScreenManagerPopScreen; */ } public override void OnGameEnd(Game game) { ScreenManager.OnPushScreen -= OnScreenManagerPushScreen; // Obsolete /* ScreenManager.OnPopScreen -= OnScreenManagerPopScreen; */ base.OnGameEnd(game); } private void OnScreenManagerPushScreen(ScreenBase pushedScreen) { if (pushedScreen is MapScreen mapScreen) { _mapView = mapScreen.AddMapView SampleMapView (Array.Empty object ()); } /* else if (pushedScreen is MissionScreen missionScreen missionScreen.Mission != null) { // MissionScreen は、まず空の MissionScreen を Push してから、ローディング画面を // 表示しつつスクリーンを初期化していく感じなので、MapScreen と同じ手法は使えません。 // // この時点で missionScreen.Mission には中身がないので、CreateMissionView() は失敗します。 _missionView = ViewCreatorManager.CreateMissionView SampleMissionView (false, missionScreen.Mission, Array.Empty object ()); missionScreen.AddMissionView(_missionView); } */ } [Obsolete("1.6.0より前の手法")] private void OnScreenManagerPopScreen(ScreenBase poppedScreen) { if (_mapView != null poppedScreen is MapScreen mapScreen) { // 1.6.0 からは MapScreen が破棄される際に勝手に MapView.OnFinalize() を呼んでくれるようになったので // MapView と MapScreen の寿命を同じにする限りでは、MapScreen.RemoveMapView() をする必要がなくなりました。 mapScreen.RemoveMapView(_mapView); _mapView = null; } else if (_missionView != null poppedScreen is MissionScreen) { // MissionView については、MissionScreen.OnEndMission() が OnMissionScreenFinalize() の呼び出しから // RemoveMissionBehaviour() まで勝手にやってくれます。 _missionView = null; } // したがって、_mapView と _missionView はもはや必要のないフィールドなのですが、説明用に残してあります。 } }} +SampleMapView.cs using ExampleUI.ViewModels;using SandBox.View.Map;using TaleWorlds.Engine.GauntletUI;using TaleWorlds.GauntletUI.Data;using TaleWorlds.InputSystem;using TaleWorlds.Library; namespace ExampleUI.Views{ public class SampleMapView MapView { private TestWindowVM _dataSource; private GauntletLayer _gauntletLayer; private IGauntletMovie _gauntletMovie; protected override void CreateLayout() { base.CreateLayout(); _dataSource = new TestWindowVM(); // localOrder (レイヤーの優先度) が小さいほど、他のレイヤーより下 (画面奥) に描画されます。 // // 例えば、部隊が町などに入った際に左に表示されるメニュー (GauntletMenuBase) のレイヤー優先度は 100 なので、 // それより小さい値に設定すればテストウィンドウがメニューの下に表示されるようになります。 // ESC メニュー (GauntletMapEscapeMenu) のレイヤー優先度が 4400 なので、これよりは小さい値に // した方がよさそうです。あるいは、ESC メニュー表示中は GUI を非表示にする処理を追加しましょう。 _gauntletLayer = new GauntletLayer(4000); Layer = _gauntletLayer; // Movie (= Screen に投影するもの) とは、XML から取得した UI の構造と、ViewModel (表示するデータ) を合わせた概念です。 _gauntletMovie = _gauntletLayer.LoadMovie("ExampleUI.Window", _dataSource); // このレイヤーの描画領域に対して行われた入力のうち、受け取るものをビットフラグによって管理しています。 _gauntletLayer.InputRestrictions.SetInputRestrictions(true, InputUsageMask.MouseButtons); MapScreen.AddLayer(_gauntletLayer); } // MapScreen.OnFinalize() によって呼び出されます。 protected override void OnFinalize() { MapScreen.RemoveLayer(_gauntletLayer); _gauntletLayer.InputRestrictions.ResetInputRestrictions(); _gauntletLayer.ReleaseMovie(_gauntletMovie); _gauntletLayer = null; Layer = null; _dataSource.OnFinalize(); base.OnFinalize(); } // 毎ティック行う処理を記述します。 // // dt デルタタイム。前回のティックからの経過時間です。 protected override void OnFrameTick(float dt) { base.OnFrameTick(dt); if (MapScreen.Input.IsKeyPressed(InputKey.Home)) { _dataSource.IsVisible ^= true; // bool 反転 } } }} +SampleMissionView.cs SampleMapView とは使用するメソッドが違うだけで、やっていることは全く同じです。 using ExampleUI.ViewModels;using TaleWorlds.Engine.GauntletUI;using TaleWorlds.GauntletUI.Data;using TaleWorlds.InputSystem;using TaleWorlds.MountAndBlade.View.Missions; namespace ExampleUI.Views{ public class SampleMissionView MissionView { private TestWindowVM _dataSource; private GauntletLayer _gauntletLayer; private IGauntletMovie _gauntletMovie; public override void OnMissionScreenInitialize() { base.OnMissionScreenInitialize(); _dataSource = new TestWindowVM(); // localOrder (レイヤーの優先度) が小さいほど、他のレイヤーより下 (画面奥) に描画されます。 // // ESC メニュー (GauntletMissionEscapeMenu) のレイヤー優先度が 50 なので、 これよりは小さい // した方がよさそうです。あるいは、ESC メニュー表示中は GUI を非表示にする処理を追加しましょう。 _gauntletLayer = new GauntletLayer(40); // Movie (= Screen に投影するもの) とは、XML から取得した UI の構造と、ViewModel (表示するデータ) を合わせた概念です。 _gauntletMovie = _gauntletLayer.LoadMovie("ExampleUI.Window", _dataSource); // このレイヤーの描画領域に対して行われた入力のうち、受け取るものをビットフラグによって管理しています。 /* _gauntletLayer.InputRestrictions.SetInputRestrictions(true, InputUsageMask.MouseButtons); */ // Mission 中はマウスを視点移動や攻撃に使うため、ポインティングデバイスとして使うには、 // 戦闘結果画面において、Tab を押す - リザルトとマウスカーソル表示 - ボタンが押せるようになる // とやっているような感じで、キーボード操作を挟んで切り替える必要があります。 // 今回はそこまで実装していないため、Mission 中は閉じるボタンをクリックできません。 MissionScreen.AddLayer(_gauntletLayer); } // MissionScreen.OnEndMission() によって呼び出されます。 public override void OnMissionScreenFinalize() { MissionScreen.RemoveLayer(_gauntletLayer); _gauntletLayer.ReleaseMovie(_gauntletMovie); _gauntletLayer = null; _dataSource.OnFinalize(); base.OnMissionScreenFinalize(); } // 毎ティック行う処理を記述します。 // // dt デルタタイム。前回のティックからの経過時間です。 public override void OnMissionScreenTick(float dt) { base.OnMissionScreenTick(dt); if (Input.IsKeyPressed(InputKey.Home)) { _dataSource.IsVisible ^= true; // bool 反転 } } }} +TestWindowVM.cs ViewModel とは View を抽象化したものです。今回の例では、 画面左上にウィンドウを表示 ウィンドウの中には閉じるボタン1つだけ 閉じるボタンを押すとウィンドウが閉じる Home キーでも開いたり閉じたりできる というモデルで行きます。 TestWindowVM は View から完全に分離されているので、今回使う2つの View どちらにもそのまま使用できます。 using TaleWorlds.Core;using TaleWorlds.Library;// View-ViewModel の参照を一方向にするため using ExampleUI.Views をやっていません。 namespace ExampleUI.ViewModels{ // ViewModel は全て TaleWorlds.Library.ViewModel を継承して作ります。 // クラス名に VM を付けなければならないという決まりがあるわけではないのですが、 // 公式の ViewModel は全て VM を付けているようなので踏襲しています。 public class TestWindowVM ViewModel { private bool _isVisible; public TestWindowVM() { IsVisible = true; } // ViewModel のプロパティやメソッドは、View の LoadMovie で関連付けられた XML Prefab から参照できます。 // XML の方を見てもらえば、それらがどのように使われているか分かるかと思います。 [DataSourceProperty] public bool IsVisible { get = _isVisible; set { if (_isVisible != value) { _isVisible = value; // このメソッドを呼ぶことで、TestWindowVM にバインディングされた View に対して // TestWindowVM.IsVisible プロパティの変更通知が行き、プロパティを参照している // ウィジェットの方も状態が変化するという仕組みです。 OnPropertyChangedWithValue(value, "IsVisible"); } } } // こちらは値の変更がない固定ラベルなので、set アクセサーや OnPropertyChangedWithValue() は使っていません。 [DataSourceProperty] public string WindowTitle = "Test Window"; // 以前はラベルにも日本語が使えたのですが、1.6.0 から文字化けするようになってしまいました。 [DataSourceProperty] public string CloseButtonLabel = "Close"; // ButtonWidget のクリックイベントに応じて呼ばれるよう、ExampleUI.Window.xml に記述してあります。 public void OnCloseButtonClick() { IsVisible = false; InformationManager.DisplayMessage(new InformationMessage("ウィンドウを閉じました。\n再度開くには Home キーを押してください。")); } }} DataSourceProperty 属性 公式の ViewModel 派生クラスのプロパティにはこの属性を与えられたものが多く見受けられますが、ソースコードを見ても特に何か定義されているわけでもなく、実際、属性を付けても付けなくても動作は変わらないように見えます。唯一、ViewModel.Properties プロパティで DataSourceProperty のリストを作るのに使われているようですが、このプロパティは他からは特に参照されていないようです。一応、XML から参照されるプロパティには全てこの属性を付けてあります。 +ExampleUI.Window.xml ExampleUI で使うウィンドウの Prefab です。 Prefab Window Widget WidthSizePolicy="Fixed" HeightSizePolicy="Fixed" SuggestedWidth="400" SuggestedHeight="300" IsVisible="@IsVisible" Children Standard.Window Parameter.Title="@WindowTitle" Children Standard.PopupCloseButton Parameter.ButtonText="@CloseButtonLabel" Parameter.ButtonAction="OnCloseButtonClick" / /Children /Standard.Window /Children /Widget /Window /Prefab Widget TaleWorlds.GauntletUI.Widget クラスです。Widget クラスは基底クラスとしてデータを保持しているだけで、UI としての機能はありません。ここでは、他の UI をまとめるコンテナとして使っています。 SizePolicy Fixed 指定の幅にしますStretchToParent 親要素の幅に合わせますCoverChildren 子要素を全て表示できる幅にします IsVisible="@IsVisible" 名前が同じで分かりにくいですが、最初の方が Widget クラスのプロパティ、@付きの方がデータソースとなる ViewModel 派生クラス (今回の例で言えば TestWindowVM) のプロパティとなります。このように指定することで、TestWindowVM.IsVisible の中で呼んである ViewModel.OnPropertyChangedWithValue() によって発せられたイベントが Widget に届くようになり、TestWindowVM.IsVisible と Widget.IsVisible が連動するわけです。 Standard.Window と Standard.PopupCloseButton 公式の Prefab を使っています。公式の Prefab も大半は各シチュエーションに特化した大型のものばかりで、そのままでの再利用はしにくいですが、Native\GUI\Prefabs\Standard にあるものは比較的小型で汎用性が高くなっています。 Parameter Standard.Window 等の Prefab では Parameter が宣言されているものがあり、Widget のプロパティに値を渡すのと同じ感覚で、Prefab 自体に値を渡すことができます。Prefab 側では、自分の中の Widget に受け取った値を渡すよう記述されています。 結果 MapScreen MissionScreen 左上にウィンドウっぽいものが表示されています。Prefab を適当に選んだのでデザインがめちゃくちゃですが、画面上にとりあえず何かを表示する例ということで大目に見てください。 手順をおおまかにまとめると、 作りたい UI を考える その構想に沿った GUI の構造 (Prefab) と表示するデータ (ViewModel) を用意する 用意したものを、表示先がワールドマップなら MapView、戦闘などの Mission なら MissionView で LoadMovie() する View をスクリーンに追加する となります。 Opponent Health Bar 今度はもう少し実践的な MOD を作っていきます。見出しが示す通り、戦っている相手の HP バーを表示する MOD です。 イメージとしてはこんな感じ。 OpponentHealthBar プロジェクトSubModule.cs MissionOpponentHealthBar.cs OpponentHealthVM.cs OpponentHealthBar.xml OpponentHealthBar.xml は、 [Bannerlord インストールフォルダー]\Modules\OpponentHealthBar\GUI\Prefabs の中に保存します。 バージョン1 それでは、とりあえず簡単に文字で表示するところから始めてみます。 +SubModule.cs using System;using TaleWorlds.MountAndBlade;using TaleWorlds.MountAndBlade.View.Missions; namespace OpponentHealthBar{ public class SubModule MBSubModuleBase { public override void OnBeforeMissionBehaviourInitialize(Mission mission) { base.OnBeforeMissionBehaviourInitialize(mission); mission.AddMissionBehaviour( ViewCreatorManager.CreateMissionView MissionOpponentHealthBar (false, mission, Array.Empty object ())); } }} +MissionOpponentHealthBar.cs using TaleWorlds.Core;using TaleWorlds.Engine.GauntletUI;using TaleWorlds.GauntletUI.Data;using TaleWorlds.MountAndBlade;using TaleWorlds.MountAndBlade.View.Missions; namespace OpponentHealthBar{ public class MissionOpponentHealthBar MissionView { private OpponentHealthVM _dataSource; private GauntletLayer _gauntletLayer; private IGauntletMovie _gauntletMovie; public MissionOpponentHealthBar() { ViewOrderPriorty = 20; } public override void OnMissionScreenInitialize() { base.OnMissionScreenInitialize(); _dataSource = new OpponentHealthVM(); _gauntletLayer = new GauntletLayer(ViewOrderPriorty); _gauntletMovie = _gauntletLayer.LoadMovie("OpponentHealthBar", _dataSource); MissionScreen.AddLayer(_gauntletLayer); } public override void OnMissionScreenFinalize() { MissionScreen.RemoveLayer(_gauntletLayer); _gauntletLayer.ReleaseMovie(_gauntletMovie); _gauntletLayer = null; _dataSource.OnFinalize(); base.OnMissionScreenFinalize(); } // 画面中央 (マウスカーソルの位置) と、一番手前にある IFocusable なオブジェクトとが交差した瞬間に呼ばれます。 // // agent フォーカスした Agent。シングルプレイだと、おそらく常に Agent.Main (プレイヤーキャラクター) です。 // focusableObject フォーカスされたもの // isInteractable Talk や Use などのインタラクトが可能か // // フォーカスが 10m までしか利かないのは MissionMainAgentInteractionComponent.FocusTick() で // 決められた仕様なのでどうしようもありません。 public override void OnFocusGained(Agent agent, IFocusable focusableObject, bool isInteractable) { base.OnFocusGained(agent, focusableObject, isInteractable); _dataSource.OnFocusChanged(focusableObject); } // 今までフォーカスされていた IFocusable なオブジェクトから、フォーカスが外れた瞬間に呼ばれます。 // // agent フォーカスしていた Agent。シングルプレイだと、おそらく常に Agent.Main (プレイヤーキャラクター) です。 // focusableObject フォーカスされていたもの public override void OnFocusLost(Agent agent, IFocusable focusableObject) { base.OnFocusLost(agent, focusableObject); _dataSource.OnFocusChanged(focusableObject); } // Agent が何らかの攻撃を受けた際に呼ばれます。 // // affectedAgent 攻撃を受けた Agent // affectorAgent 攻撃を行った Agent // damage ダメージ量 // affectorWeapon 使用された武器 public override void OnAgentHit(Agent affectedAgent, Agent affectorAgent, int damage, in MissionWeapon affectorWeapon) { base.OnAgentHit(affectedAgent, affectorAgent, damage, affectorWeapon); _dataSource.OnAgentHit(affectedAgent); } // Agent が戦闘不能になった際に呼ばれます。 // // affectedAgent 攻撃を受けた Agent // affectorAgent 攻撃を行った Agent // agentState Agent の状態 // blow とどめの一撃の内容 // // 似たようなメソッドに OnAgentDeleted がありますが、そちらは // 戦闘不能になって倒れている Agent が時間経過や表示限界により消滅する際に呼ばれるようです。 public override void OnAgentRemoved(Agent affectedAgent, Agent affectorAgent, AgentState agentState, KillingBlow blow) { base.OnAgentRemoved(affectedAgent, affectorAgent, agentState, blow); _dataSource.OnAgentRemoved(affectedAgent); } }} +OpponentHealthVM.cs 今度のモデルは、 Agent (Mission 中に動きうるもの) の HP 現在値/最大値 を文字で表示する Agent にフォーカスが合うと表示、フォーカスが外れると非表示 とします。 using System;using TaleWorlds.Library;using TaleWorlds.MountAndBlade; namespace OpponentHealthBar{ public class OpponentHealthVM ViewModel { private Agent _opponent; private string _strValues; private bool _isVisible; private const string ValueFormat = "{0} / {1}"; public OpponentHealthVM() { _opponent = null; _strValues = string.Empty; _isVisible = false; } [DataSourceProperty] public string StrValues { get = _strValues; private set { if (_strValues != value) { _strValues = value; OnPropertyChangedWithValue(value, "StrValues"); } } } [DataSourceProperty] public bool IsVisible { get = _isVisible; set { if (_isVisible != value) { _isVisible = value; OnPropertyChangedWithValue(value, "IsVisible"); } } } // GUI に表示するデータの更新はこのメソッドで行います。 // ただし、ここに記述すればあとは勝手に更新されていくというものではないので、 // 自分が必要な場所では自分で呼び出さなければなりません。 public override void RefreshValues() { base.RefreshValues(); int currentValue = (int)Math.Ceiling(_opponent?.Health ?? 0f); int maxValue = (int)Math.Ceiling(_opponent?.HealthLimit ?? 0f); StrValues = string.Format(ValueFormat, currentValue, maxValue); IsVisible = _opponent != null; } public void OnFocusChanged(IFocusable focusableObject) { if (focusableObject is Agent possibleOpponent) { _opponent = (_opponent == null || _opponent != possibleOpponent) ? possibleOpponent null; RefreshValues(); } } public void OnAgentHit(Agent affectedAgent) { if (_opponent == affectedAgent) { RefreshValues(); } } public void OnAgentRemoved(Agent removedAgent) { if (_opponent == removedAgent) { // 先にフォーカスロストが発生してここには入らないかも。 OnFocusChanged(removedAgent); } } }} +OpponentHealthBar.xml Prefab Window Widget WidthSizePolicy="Fixed" HeightSizePolicy="Fixed" SuggestedWidth="430" SuggestedHeight="50" HorizontalAlignment="Center" VerticalAlignment="Top" MarginTop="250" IsVisible="@IsVisible" Children TextWidget Text="@StrValues" WidthSizePolicy="CoverChildren" HeightSizePolicy="CoverChildren" HorizontalAlignment="Center" VerticalAlignment="Center" Brush="Tooltip.Text" Brush.FontSize="24" / /Children /Widget /Window /Prefab Alignment 親要素の領域内のどちら側に寄せるかです。親要素より幅が小さい場合にしか効果がありません。この例の TextWidget で言うと、親要素は幅 430、自身は CoverChildren、つまり StrValues が入りきるだけの幅なので機能していますが、これを StretchToParent とかにすると、左寄せや右寄せが機能しなくなります。 Margin Left, Top, Right, Bottom のマージンです。幅+マージンが要素の実際の幅になります。 以上を実行した状態が下の画像です。 ちょっと見にくいですが、画面上部中央に相手の HP 100/100 が表示されていますね。フォーカスを外せば数字は消えます。しかし、今のところ町人だろうが馬だろうが Agent なら何にでも表示されてしまいますので、そこは改良が必要です。 バージョン2 次はバーの導入とその他の改良を行っていきたいと思います。 バー表示に使うのは FillBarWidget です。ソースコードや、FillBarWidget を使用している公式の Prefab を見てみると、FillBarWidget.MaxAmount プロパティと FillBarWidget.InitialAmmount プロパティに値を渡せばとりあえず動きそうです。よって、ViewModel 側でその値を用意してやる必要があります。 +OpponentHealthVM.cs [DataSourceProperty] public int CurrentValue { get = _currentValue; private set { if (_currentValue != value) { _currentValue = value; OnPropertyChangedWithValue(value, "CurrentValue"); } } } [DataSourceProperty] public int MaxValue { get = _maxValue; private set { if (_maxValue != value) { _maxValue = value; OnPropertyChangedWithValue(value, "MaxValue"); } } } // GUI に表示するデータの更新はこのメソッドで行います。 // ただし、ここに記述すればあとは勝手に更新されていくというものではないので、 // 自分が必要な場所では自分で呼び出さなければなりません。 public override void RefreshValues() { base.RefreshValues(); // 元々ローカル変数だったものを、View から参照できるようにプロパティに昇格しました。 CurrentValue = (int)Math.Ceiling(_opponent?.Health ?? 0f); MaxValue = (int)Math.Ceiling(_opponent?.HealthLimit ?? 0f); StrValues = string.Format(ValueFormat, CurrentValue, MaxValue); IsVisible = _opponent != null; } public void OnFocusChanged(IFocusable focusableObject) { // 適切な相手に表示されるよう条件を追加しました。 if (focusableObject is Agent possibleOpponent possibleOpponent.IsHuman possibleOpponent.IsEnemyOf(Agent.Main)) { _opponent = (_opponent == null || _opponent != possibleOpponent) ? possibleOpponent null; RefreshValues(); } } ViewModel にプロパティを追加したので、今度は Prefab を通じてそれらを FillBarWidget に渡します。 +OpponentHealthBar.xml Prefab Window FillBarWidget WidthSizePolicy="Fixed" HeightSizePolicy="Fixed" SuggestedWidth="430" SuggestedHeight="50" HorizontalAlignment="Center" VerticalAlignment="Top" MarginTop="250" ContainerWidget="FillBarContainer" FillWidget="FillVisualParent\FillVisual" MaxAmount="@MaxValue" InitialAmount="@CurrentValue" IsVisible="@IsVisible" Children Widget Id="FillVisualParent" WidthSizePolicy="Fixed" HeightSizePolicy="StretchToParent" SuggestedWidth="400" HorizontalAlignment="Center" VerticalAlignment="Center" MarginTop="10" MarginBottom="10" Sprite="BlankWhiteSquare" Color="#202020A0" Children BrushWidget Id="FillVisual" WidthSizePolicy="Fixed" HeightSizePolicy="StretchToParent" SuggestedWidth="400" HorizontalAlignment="Left" Brush="Mission.MainAgentHUD.HeroHealthBar.Fill" / /Children /Widget Widget Id="FillBarContainer" WidthSizePolicy="StretchToParent" HeightSizePolicy="StretchToParent" Sprite="options_memory_progress_frame" / TextWidget Text="@StrValues" WidthSizePolicy="CoverChildren" HeightSizePolicy="CoverChildren" HorizontalAlignment="Center" VerticalAlignment="Center" PositionYOffset="3" Brush="Tooltip.Text" Brush.FontSize="24" / /Children /FillBarWidget /Window /Prefab FillBarWidget バージョン1ではただの Widget だったトップレベルのウィジェットを FillBarWidget に変更してあります (3行目)。 FillVisual 赤ゲージの Brush を保持した BrushWidget の ID です (9行目)。このように、Widget には任意の ID がつけられます。それによって、他のウィジェットを操作するタイプのウィジェットに対し、操作対象がどれなのか伝えることができます。 ここでは、FillBarWidget.FillWidget プロパティに渡して、FillBarWidget が "FillVisual" の幅を操作できるようにしています。 親要素の "FillVisualParent" はゲージが減った部分を埋める背景画像です。"BlankWhiteSquare" という無地画像を、暗い半透明に着色・透過させて使っています。 FillBarContainer 14行目にある、スプライト画像を保持した Widget の ID です。これを FillBarWidget.ContainerWidget プロパティに渡してバーの枠としています。 ところで、Mission 用の GUI はそのままだとフォトモード中でも表示されてしまいます。構図を決めている間に GUI が表示されてしまうのは邪魔ですから、MissionView を使うときは、フォトモード中 GUI を非表示にする処理を追加しておきましょう。 +MissionOpponentHealthBar.cs // フォトモードで構図を決めている最中に GUI が表示されないようにするための処理です。 // この処理を入れても入れなくても、どちらにしろ出力される画像ファイルに GUI は写りません。 public override void OnPhotoModeActivated() { base.OnPhotoModeActivated(); _gauntletLayer._gauntletUIContext.ContextAlpha = 0f; } public override void OnPhotoModeDeactivated() { base.OnPhotoModeDeactivated(); _gauntletLayer._gauntletUIContext.ContextAlpha = 1f; } 結果 攻撃前 攻撃後 どうでしょう、一応 HP バーらしくなったのではないでしょうか。 他にも、与えたダメージ分のバーをスライドさせる視覚効果とか、フォーカスが外れてからバーが消えるまでに時間差を設けるとか、改良はいろいろ考えられますが、サンプルではここまでです。興味があったら自分の MOD として実装してみてください。 +コード最終形 SubModule.cs using System;using TaleWorlds.MountAndBlade;using TaleWorlds.MountAndBlade.View.Missions; namespace OpponentHealthBar{ public class SubModule MBSubModuleBase { public override void OnBeforeMissionBehaviourInitialize(Mission mission) { base.OnBeforeMissionBehaviourInitialize(mission); mission.AddMissionBehaviour( ViewCreatorManager.CreateMissionView MissionOpponentHealthBar (false, mission, Array.Empty object ())); } }} MissionOpponentHealthBar.cs using TaleWorlds.Core;using TaleWorlds.Engine.GauntletUI;using TaleWorlds.GauntletUI.Data;using TaleWorlds.MountAndBlade;using TaleWorlds.MountAndBlade.View.Missions; namespace OpponentHealthBar{ public class MissionOpponentHealthBar MissionView { private OpponentHealthVM _dataSource; private GauntletLayer _gauntletLayer; private IGauntletMovie _gauntletMovie; public MissionOpponentHealthBar() { ViewOrderPriorty = 20; } public override void OnMissionScreenInitialize() { base.OnMissionScreenInitialize(); _dataSource = new OpponentHealthVM(); _gauntletLayer = new GauntletLayer(ViewOrderPriorty); _gauntletMovie = _gauntletLayer.LoadMovie("OpponentHealthBar", _dataSource); MissionScreen.AddLayer(_gauntletLayer); } public override void OnMissionScreenFinalize() { MissionScreen.RemoveLayer(_gauntletLayer); _gauntletLayer.ReleaseMovie(_gauntletMovie); _gauntletLayer = null; _dataSource.OnFinalize(); base.OnMissionScreenFinalize(); } // 画面中央 (マウスカーソルの位置) と、一番手前にある IFocusable なオブジェクトとが交差した瞬間に呼ばれます。 // // agent フォーカスした Agent。シングルプレイだと、おそらく常に Agent.Main (プレイヤーキャラクター) です。 // focusableObject フォーカスされたもの // isInteractable Talk や Use などのインタラクトが可能か // // フォーカスが 10m までしか利かないのは MissionMainAgentInteractionComponent.FocusTick() で // 決められた仕様なのでどうしようもありません。 public override void OnFocusGained(Agent agent, IFocusable focusableObject, bool isInteractable) { base.OnFocusGained(agent, focusableObject, isInteractable); _dataSource.OnFocusChanged(focusableObject); } // 今までフォーカスされていた IFocusable なオブジェクトから、フォーカスが外れた瞬間に呼ばれます。 // // agent フォーカスしていた Agent。シングルプレイだと、おそらく常に Agent.Main (プレイヤーキャラクター) です。 // focusableObject フォーカスされていたもの public override void OnFocusLost(Agent agent, IFocusable focusableObject) { base.OnFocusLost(agent, focusableObject); _dataSource.OnFocusChanged(focusableObject); } // Agent が何らかの攻撃を受けた際に呼ばれます。 // // affectedAgent 攻撃を受けた Agent // affectorAgent 攻撃を行った Agent // damage ダメージ量 // affectorWeapon 使用された武器 public override void OnAgentHit(Agent affectedAgent, Agent affectorAgent, int damage, in MissionWeapon affectorWeapon) { base.OnAgentHit(affectedAgent, affectorAgent, damage, affectorWeapon); _dataSource.OnAgentHit(affectedAgent); } // Agent が戦闘不能になった際に呼ばれます。 // // affectedAgent 攻撃を受けた Agent // affectorAgent 攻撃を行った Agent // agentState Agent の状態 // blow とどめの一撃の内容 // // 似たようなメソッドに OnAgentDeleted がありますが、そちらは // 戦闘不能になって倒れている Agent が時間経過や表示限界により消滅する際に呼ばれるようです。 public override void OnAgentRemoved(Agent affectedAgent, Agent affectorAgent, AgentState agentState, KillingBlow blow) { base.OnAgentRemoved(affectedAgent, affectorAgent, agentState, blow); _dataSource.OnAgentRemoved(affectedAgent); } // フォトモードで構図を決めている最中に GUI が表示されないようにするための処理です。 // この処理を入れても入れなくても、どちらにしろ出力される画像ファイルに GUI は写りません。 public override void OnPhotoModeActivated() { base.OnPhotoModeActivated(); _gauntletLayer._gauntletUIContext.ContextAlpha = 0f; } public override void OnPhotoModeDeactivated() { base.OnPhotoModeDeactivated(); _gauntletLayer._gauntletUIContext.ContextAlpha = 1f; } }} OpponentHealthVM.cs using System;using TaleWorlds.Library;using TaleWorlds.MountAndBlade; namespace OpponentHealthBar{ public class OpponentHealthVM ViewModel { private Agent _opponent; private int _currentValue; private int _maxValue; private string _strValues; private bool _isVisible; private const string ValueFormat = "{0} / {1}"; public OpponentHealthVM() { _opponent = null; _strValues = string.Empty; _isVisible = false; } [DataSourceProperty] public int CurrentValue { get = _currentValue; private set { if (_currentValue != value) { _currentValue = value; OnPropertyChangedWithValue(value, "CurrentValue"); } } } [DataSourceProperty] public int MaxValue { get = _maxValue; private set { if (_maxValue != value) { _maxValue = value; OnPropertyChangedWithValue(value, "MaxValue"); } } } [DataSourceProperty] public string StrValues { get = _strValues; private set { if (_strValues != value) { _strValues = value; OnPropertyChangedWithValue(value, "StrValues"); } } } [DataSourceProperty] public bool IsVisible { get = _isVisible; set { if (_isVisible != value) { _isVisible = value; OnPropertyChangedWithValue(value, "IsVisible"); } } } // GUI に表示するデータの更新はこのメソッドで行います。 // ただし、ここに記述すればあとは勝手に更新されていくというものではないので、 // 自分が必要な場所では自分で呼び出さなければなりません。 public override void RefreshValues() { base.RefreshValues(); // 元々ローカル変数だったものを、View から参照できるようにプロパティに昇格しました。 CurrentValue = (int)Math.Ceiling(_opponent?.Health ?? 0f); MaxValue = (int)Math.Ceiling(_opponent?.HealthLimit ?? 0f); StrValues = string.Format(ValueFormat, CurrentValue, MaxValue); IsVisible = _opponent != null; } public void OnFocusChanged(IFocusable focusableObject) { // 適切な相手に表示されるよう条件を追加しました。 if (focusableObject is Agent possibleOpponent possibleOpponent.IsHuman possibleOpponent.IsEnemyOf(Agent.Main)) { _opponent = (_opponent == null || _opponent != possibleOpponent) ? possibleOpponent null; RefreshValues(); } } public void OnAgentHit(Agent affectedAgent) { if (_opponent == affectedAgent) { RefreshValues(); } } public void OnAgentRemoved(Agent removedAgent) { if (_opponent == removedAgent) { // 先にフォーカスロストが発生してここには入らないかも。 OnFocusChanged(removedAgent); } } }} OpponentHealthBar.xml Prefab Window FillBarWidget WidthSizePolicy="Fixed" HeightSizePolicy="Fixed" SuggestedWidth="430" SuggestedHeight="50" HorizontalAlignment="Center" VerticalAlignment="Top" MarginTop="250" ContainerWidget="FillBarContainer" FillWidget="FillVisualParent\FillVisual" MaxAmount="@MaxValue" InitialAmount="@CurrentValue" IsVisible="@IsVisible" Children Widget Id="FillVisualParent" WidthSizePolicy="Fixed" HeightSizePolicy="StretchToParent" SuggestedWidth="400" HorizontalAlignment="Center" VerticalAlignment="Center" MarginTop="10" MarginBottom="10" Sprite="BlankWhiteSquare" Color="#202020A0" Children BrushWidget Id="FillVisual" WidthSizePolicy="Fixed" HeightSizePolicy="StretchToParent" SuggestedWidth="400" HorizontalAlignment="Left" Brush="Mission.MainAgentHUD.HeroHealthBar.Fill" / /Children /Widget Widget Id="FillBarContainer" WidthSizePolicy="StretchToParent" HeightSizePolicy="StretchToParent" Sprite="options_memory_progress_frame" / TextWidget Text="@StrValues" WidthSizePolicy="CoverChildren" HeightSizePolicy="CoverChildren" HorizontalAlignment="Center" VerticalAlignment="Center" PositionYOffset="3" Brush="Tooltip.Text" Brush.FontSize="24" / /Children /FillBarWidget /Window /Prefab 名前
https://w.atwiki.jp/ets2wiki/pages/25.html
ゲームシステム・環境構築ゲームシステム 環境改善 AI改善 Physics改善 ワールド トラクター編メーカー共通 DAF Iveco MAN Mercedes-Benz Renault Volvo トレーラー マップ その他 コメント ほとんど同じmodばかりだがたまにそこにしかない物もあったりする URL 備考 http //ets2.lt/en/ http //etsmods.net/ http //ets2mods.com/en/ http //pete379jp.s69.xrea.com/ 18輪皮置き場 ゲームシステム・環境構築 ゲームシステム 環境改善 AI改善 MOD名 AI Traffic Pack by Jazzycat v5.9 概要 AI車を新たに291種類追加するmod。 入手場所 1.28.x⇛ets2.lt 備考 MOD名 Bus Traffic Pack by Jazzycat v2.6 概要 AIの大型バスを追加したりデフォルトのAIバスの色を追加するMod。 入手場所 1.28.x⇛ets2.lt 備考 AIのバスを追加するMod。約27種類のバスと約324種類のスキンを追加する。 MOD名 Truck Traffic Pack by Jazzycat v2.8 概要 AIのセミトレーラー・フルトレーラー、単車(トラック)を追加するMod。 入手場所 1.28.x⇛ets2.lt 備考 MOD名 GTA IV Traffic Pack v 1.0 update 概要 GTA IVの車をAIに追加するmod。 入手場所 1.21.x⇛ets2.lt 備考 次の「Saints Row 3 traffic pack v3」とは現時点で同時に使用できないので注意が必要。 MOD名 Saints Row 3 traffic pack v3 概要 Saints Row 3の車をAIに追加するmod。 入手場所 1.19.x⇛ets2.lt 備考 前の「GTA IV Traffic Pack」とは現時点で同時に使用できないので注意が必要。 Physics改善 MOD名 Modfied Sawmill 概要 落ちている木材にあたり判定をつけるmod。 入手場所 1.20.x⇛ets2.lt 備考 ワールド トラクター編 メーカー共通 MOD名 BDF Tandem Truck Pack v38.0 概要 フルトラクタを追加するMod。 入手場所 1.19.x→etsmods.net 備考 フルトラクタを追加するMod。荷台のスキンは変更可能。 DAF MOD名 DAF XF Euro6 by ohaha (v1.44) 概要 DAFトラックのカスタムmod 入手場所 1.21.x⇛forum.scssoft.com 備考 DAFのディーラーに行き、「DAF XF Euro6 ohaha」を選択することで使える。スキンmodやサウンドmodは新たにこのmod専用に導入が必要。ets2.ltなどで、「DAF ohaha skin」などと検索し適用する必要がある。 Iveco MAN MOD名 MAN TGX Euro6 (v1.6) 概要 MANトラックの追加・カスタムmod 入手場所 1.23.x⇛forum.scssoft.com 備考 MANのディーラーに行き、「MAN TGX Euro6」を選択することで使える。スキンmodやサウンドmodは新たにこのmod専用に導入が必要。ets2.ltなどで、「MAN TGX Euro6 skin」などと検索し適用する必要がある。 注意 v1.6で右ハンドルを選択するとHUDミラー(F2ミラー)が左右逆に表示されるため、右ハンドルで乗る人はv1.5を使用すること。 Mercedes-Benz Renault MOD名 Scania R Streamline Modifications V1.5.1.1 概要 Scaniaトラックのカスタムmod 入手場所 1.23.x⇛forum.scssoft.com 備考 Scaniaのディーラーに行き、「Scania R(RJL)Normal」を選択することで使える。スキンmodやサウンドmodは新たにこのmod専用に導入が必要。ets2.ltなどで、「Scania rjl skin」などと検索し適用する必要がある。 MOD名 Scania T Mod V1.8.1.1 概要 Scania Tシリーズトラックを追加するmod。 入手場所 1.23.x⇛forum.scssoft.com 備考 Scaniaのディーラーに行き、「Scania T Normal」を選択することで使える。通常のものと比べて、トラックの形状が違うので、操作にはある程度の慣れが必要。#参考画像1 #参考画像2 実車の動画 Volvo MOD名 Volvo FH 2013 [ohaha] v19.6s 概要 Volvoトラックのカスタムmod 入手場所 1.23.x⇛forum.scssoft.com 備考 Volvoのディーラーに行って、「volvo ohaha」を選択することで使える。ただし、スキンmodやサウンドmodは新たにこのmod専用に導入が必要。ets2.ltなどで、「Volvo ohaha(もしくは2013) skin」などと検索し適用する必要がある。 トレーラー MOD名 Japan Trailers Traffic Pack v 3.0 概要 日本の企業のトレーラーを追加するmod。 入手場所 1.19.2.1⇛ets2.lt 備考 MOD名 Trailers and Cargo Pack by Jazzycat v5.5 概要 大量のトレーラーを追加するmod。合わせて8x4のAIトラクタも追加される。 入手場所 1.28.x⇛ets2.lt 備考 trailers_and_cargo_pack_by_Jazzycat_v5.5_part1.scstrailers_and_cargo_pack_by_Jazzycat_v5.5_part2.scstrailers_and_cargo_pack_by_Jazzycat_v5.5_eng.scsの3つのファイルをmodフォルダに入れて導入してください。 MOD名 Military Cargo Pack by Jazzycat v 1.7 概要 戦車など軍事車両系の荷物が運べるようになるmod。 入手場所 1.23.x→forum.scssoft.com 備考 military_cargo_pack_by_Jazzycat_v1.7_base.scsmilitary_cargo_pack_by_Jazzycat_v1.7_eng.scsの2つのファイルをmodフォルダに入れて適用してください。military_cargo_pack_by_Jazzycat_v1.7_traffic.scsを適用すると、AIトラックがこのmodのトレーラーを運搬するようになる。・v1.23でのタイヤ・ホイールおよび5軸以上のトレーラーの問題と注意点は"Trailers and Cargo Pack by Jazzycat"と同様。 MOD名 Railway Cargo Pack by Jazzycat v 1.7.1 概要 機関車・客車・貨車など鉄道車両系の荷物が運べるようになるmod。 入手場所 1.23.x→forum.scssoft.com 備考 railway_cargo_pack_by_Jazzycat_v1.7.1_base.scsrailway_cargo_pack_by_Jazzycat_v1.7.1_eng.scsの2つのファイルをmodフォルダに入れて適用してください。・v1.23でのタイヤ・ホイールおよび5軸以上のトレーラーの問題と注意点は"Trailers and Cargo Pack by Jazzycat"と同様。 MOD名 68 Roadhunter Trailers in One Pack Version 5.2 概要 重たくかつ大きいトレーラーを追加するmod。 入手場所 1.21.x⇛ets2.lt 備考 マップ MOD名 TruckSimMap 6.2 for Patch 1.22.x 概要 主に地中海周辺国を追加し、デフォルトMapにも少し変更を加えるmod。 入手場所 1.22.x→ets2.ltもしくはforum.scssoft.com 備考 v6.2からはGoing East! およびスカンジナビアのマップDLCが必要。解凍できない場合には7-Zipを使用してください。 MOD名 EAA Map v 2.8.3 概要 ブラジルMapを追加するMod。 入手場所 1.21.x→ets2.lt 備考 マップ系のDLCがあってもなくても使える。解凍時にパスワードを求められた場合は「#alwayseaa」と入力してください。 ProMods 有名なmod。細部に拘っている。v2.02はv1.23.xに対応・Going East! およびスカンディナビアDLCが必要。このページからregisterでアカウントを作成、ログインしDownloadからダウンロード。・v2.02についてはHotfix2、またはHotfix3が必要。 その他 MOD名 Brutal Environment HD + Sound + Engine Gold 2015 for 1.21.x 概要 いろいろ改善するmod。詳しくは備考を見てください。 入手場所 1.21.x⇛ets2.lt 備考 ONLY HD ENGINE→グラフィック改善。FPSが10%向上する。HDRはONにし、色補正はOFFにしてください。ONLY SOUND ENGINE→ゲーム内の音を変更する。ONLY EXTERNAL VOLUME UP→車内にいるときの外の環境音を大きくする。優先度を最大にして使用してください。BRUTAL ADVISER→ルートアドバイザーなどの表示位置の変更。NO DAMAGE + FREE TOLGATE→ダメージを受けなくなる。料金所のバーが消える。 コメント
https://w.atwiki.jp/toho/pages/2245.html
NOSTALGIA サークル:Sound Online Number Track Name Arranger Lyrics Vocal Original Works Original Tune Length 01 Mirage of the Rain Tsukasa - 東方星蓮船 青空の影 [01 42] 02 Survive 野宮 あゆみ 坂上 なち 東方妖々夢 東方妖々夢 ~ Ancient Temple [05 43] 03 Seek Your Mind 三澤 秋 美里 東方紅魔郷 亡き王女の為のセプテット [05 43] 04 Mystic Water Masayoshi Minoshima - 東方怪綺談 Mystic Dream [07 18] 05 Firebird Tsukasa - 東方地霊殿 ハルトマンの妖怪少女 [06 29] 06 Detector TsukasaGuitar a2c 野宮 あゆみ 東方星蓮船 小さな小さな賢将 [04 44] 07 Cosmos Glide Tsukasa 三澤 秋 東方風神録 明日ハレの日、ケの昨日 [05 35] 08 Graven Image REDALiCE - 東方風神録 御柱の墓場 ~ Grave of Being [04 00] 09 Drake Tsukasa - 東方紅魔郷 U.N.オーエンは彼女なのか? [05 17] 10 Nostalgia 三澤 秋 東方地霊殿 ラストリモート [05 42] 詳細 コミックマーケット76(2009/08/15)にて頒布 イベント価格:1000円 ショップ価格:1429円(税込:1500円) Arranger Masayoshi Minoshima: (Alstroemeria Records) REDALiCE: (ALiCE S EMOTiON) レビュー スルメのような逸品。繰り返し聞いているとアルバム全体の構成の良さにセンスを感じる。アルバムタイトルを冠したTr.10へ流れるように繋がっていく構成は聞いていて本当に気持ちがイイ。 お気に入りはTr.3.4.7.10 Tr.9のアレンジでグラディウスが聞こえたのは私だけだろうか?w -- copper (2009-09-19 02 00 56) 3trの亡き王女の為のセプテットアレンジが傑作。 このアルバムでTsukasaさんのファンになりました。 -- 名無しさん (2011-04-10 00 47 33) 全体的に質が高くて捨て曲が無いと思いました。 ハイテンポの曲とゆったりした曲のバランスも良く一枚通して聞きやすいです。 -- 名無しさん (2011-04-10 17 07 19) CDのタイトルにもなっている「Nostalgia」は非常に完成度の高い曲でした。 個人的には東方アレンジの中で最も好きなアルバムです。 -- 名無しさん (2011-05-18 00 31 57) Drakeは一年以上捜し求めていただけに出逢えた感動は強い。 オーエンの純粋なインストアレンジならば一番好き。 Nostalgiaは歌詞、曲調、ボーカル共にラストリモートの最高峰だと思う。 -- 反射Sound (2011-06-14 13 17 31) 名前 コメント
https://w.atwiki.jp/ups_mc/pages/10.html
主要MOD Create 工業化MOD スチームパンクの世界観を持っている 歯車や機械など非常にグラフィカルなのが特徴 鉄道も引ける マイクラ Create mod日本語wiki Create Japan Wiki 「Create」Mod初心者向け解説。水車と歯車で動かす工業化Mod Create始め方・使い方解説【MOD】minecraft【1.19.2】 Create 追加アドオン Blood Magic 魔術系MOD 自らの血を捧げることによって、様々な魔術や儀式を行うMOD Minecraft Japan Wiki MOD解説/BloodMagic2 Botania 魔術系MOD 特殊な花などから“マナ”を生成し集約させることにより機器を動作させる。 MPO.GG - マイクラMod「Botania」序盤解説。花を使った魔術Mod Minecraft Japan Wiki MOD解説/Botania Mine Colonies 自分のワールドにNPC達の入植地(Colony)を招致できるMOD。 コロニーを発展させる事で鉱石・原木・作物・畜産・釣り・粘土等の 資源を自動で収集できるようになる。 MPO.GG - マイクラMod「MineColonies」解説。村人を使って街作り MINE-TECH - 自分だけの街をつくろう!『MineColonies』で激変マイクラ生活!MOD導入&質問と回答編 ストレージ系 Refined Storage 高性能大容量の倉庫管理MOD MPO.GG - マイクラMod「Refined Storage」最小構成から解説。超大容量・検索・作業台付きストレージ Colossal Chests 複数のブロックを使って大きく大容量なチェストを作成できる。 マイクラMOD解説屋 - 超巨大ロマンチェストColossal Chests Storage Drawers 多機能な引き出しを作成できる。 PAY-Project - Storage Drawers MOD解説 Compact Storage 色や容量などをカスタマイズできるチェストを作成できる。 バックパックも作れる。 冒険 The Twilight Forest 冒険要素メインの新ディメンションを追加する。 MOD解説/The Twilight Forest - Minecraft Japan Wiki ペット強化 Domestication Innovation 自由行動させるモードの追加、フレンドリーファイアの防止など、 バニラのオオカミやネコのようなペットの仕様を改善する。 27代目のネコ - Domestication Innovation解説『アイテム・エンチャント解説』 クエスト強化 Origins FTB Quest クエストを追加する。 MINE-TECH まとめて紹介!『FTB Teams・Quests・Essentials』解説&日本語化リソースパック配布 乗り物系 Valkryien Skies ブロックで作った建造物を飛ばせるようにするMOD 日刊まっちゃん - Eureka! Ships! for Valkyrien Skiesの紹介 使い方解説 Simple Planes (導入予定) シンプルな飛行機やヘリコプターを追加する java版 マイクラ 飛行機MOD Simple Planes MODを紹介 テレポート Waystones MPO.GG - マイクラMod「Waystones」解説。使用型/設置型ワープアイテム 武器追加 Age of Weapons 様々な時代の武器を追加するMOD。 武器は、刃と柄、その他のパーツを組み合わせて作成する。 抜刀剣MOD 刀剣が追加される。 マイクラゼボブログ - 超リアルな日本刀で遊べる!刀modの抜刀剣の入れ方と遊び方! MOB追加 Grimoire of Gaia 4